<template>
  <view class="container">
    <view class="header">
      <text class="title">微信支付示例</text>
    </view>

    <view class="form-item">
      <text class="label">商品名称：</text>
      <text class="value">测试商品</text>
    </view>

    <view class="form-item">
      <text class="label">支付金额：</text>
      <input class="input" type="digit" v-model="amount" placeholder="请输入金额（元）" />
    </view>

    <button class="pay-btn" type="primary" @click="requestPayment">立即支付</button>
    

    <view class="tip">支付金额将转换为分进行支付</view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      amount: '0.01',  // 默认支付金额为0.01元
      orderNo: '',  // 订单号
      server: 'http://localhost:8080/api/pay/wechat'  // 请替换为您的后端接口地址
    }
  },
  methods: {
    // 生成订单号
    generateOrderNo() {
      const now = new Date()
      return 'WX' + now.getFullYear() +
        this.pad(now.getMonth() + 1) +
        this.pad(now.getDate()) +
        this.pad(now.getHours()) +
        this.pad(now.getMinutes()) +
        this.pad(now.getSeconds()) +
        this.pad(now.getMilliseconds(), 3) +
        Math.floor(Math.random() * 1000).toString().padStart(3, '0')
    },

    // 数字补零
    pad(num, length = 2) {
      return String(num).padStart(length, '0')
    },

    // 请求支付
    requestPayment() {
      if (!this.amount || isNaN(this.amount) || parseFloat(this.amount) <= 0) {
        uni.showToast({
          title: '请输入有效金额',
          icon: 'none'
        })
        return
      }

      // 显示加载中
      uni.showLoading({
        title: '请求支付中...'
      })

      // 生成订单号
      this.orderNo = this.generateOrderNo()

      // 将元转换为分
      const totalFee = Math.floor(parseFloat(this.amount) * 100)

      // 获取用户openid
      this.getOpenid().then(openid => {
        // 请求后端获取支付参数
        uni.request({
          url: `${this.server}/mini-app`,
          method: 'POST',
          data: {
            orderNo: this.orderNo,
            description: '测试商品',
            totalFee: totalFee,
            openid: openid
          },
          success: (res) => {
            uni.hideLoading()

            if (res.statusCode !== 200) {
              uni.showToast({
                title: '获取支付参数失败',
                icon: 'none'
              })
              return
            }

            // 发起微信支付
            this.launchWechatPay(res.data)
          },
          fail: () => {
            uni.hideLoading()
            uni.showToast({
              title: '网络请求失败',
              icon: 'none'
            })
          }
        })
      }).catch(err => {
        uni.hideLoading()
        uni.showToast({
          title: '获取用户信息失败: ' + err.message,
          icon: 'none'
        })
      })
    },

    // 获取用户openid
    getOpenid() {
      return new Promise((resolve, reject) => {
        uni.login({
          provider: 'weixin',
          success: (loginRes) => {
            if (loginRes.code) {
              // 调用后端接口获取openid
              uni.request({
                url: `${this.server.replace('/api/pay/wechat', '')}/api/wechat/miniapp/openid`,
                method: 'POST',
                data: {
                  code: loginRes.code
                },
                success: (res) => {
                  if (res.data && res.data.openid) {
                    resolve(res.data.openid);
                  } else {
                    reject(new Error('获取openid失败'));
                  }
                },
                fail: (err) => {
                  reject(err);
                }
              });
            } else {
              reject(new Error('登录失败'));
            }
          },
          fail: (err) => {
            reject(err);
          }
        });
      });
    },

    // 拉起微信支付
    launchWechatPay(payParams) {
      uni.requestPayment({
        provider: 'wxpay',
        timeStamp: payParams.timeStamp,
        nonceStr: payParams.nonceStr,
        package: payParams.package,
        signType: payParams.signType,
        paySign: payParams.paySign,
        success: (res) => {
          console.log('支付成功', res)
          uni.showToast({
            title: '支付成功',
            icon: 'success'
          })

          // 跳转到支付结果页
          uni.navigateTo({
            url: '/pages/result/result?status=success&orderNo=' + this.orderNo
          })
        },
        fail: (err) => {
          console.log('支付失败', err)
          if (err.errMsg === 'requestPayment:fail cancel') {
            uni.showToast({
              title: '用户取消支付',
              icon: 'none'
            })
          } else {
            uni.showToast({
              title: '支付失败',
              icon: 'none'
            })

            // 跳转到支付结果页
            uni.navigateTo({
              url: '/pages/result/result?status=fail&orderNo=' + this.orderNo
            })
          }
        }
      })
    },

    // 快速支付版本（无需获取openid）
    quickPay() {
      if (!this.amount || isNaN(this.amount) || parseFloat(this.amount) <= 0) {
        uni.showToast({
          title: '请输入有效金额',
          icon: 'none'
        });
        return;
      }
      
      // 显示加载中
      uni.showLoading({
        title: '请求支付中...'
      });
      
      // 将元转换为分
      const totalFee = Math.floor(parseFloat(this.amount) * 100);
      
      // 获取登录code
      uni.login({
        provider: 'weixin',
        success: (loginRes) => {
          if (loginRes.code) {
            // 请求后端，一步到位获取支付参数
            uni.request({
              url: `${this.server}/mini-app/quick`,
              method: 'POST',
              data: {
                description: '测试商品',
                totalFee: totalFee,
                code: loginRes.code
              },
              success: (res) => {
                uni.hideLoading();
                
                if (res.statusCode !== 200 || !res.data.payParams) {
                  uni.showToast({
                    title: '获取支付参数失败',
                    icon: 'none'
                  });
                  return;
                }
                
                // 保存订单号
                this.orderNo = res.data.orderNo;
                
                // 发起微信支付
                this.launchWechatPay(res.data.payParams);
              },
              fail: () => {
                uni.hideLoading();
                uni.showToast({
                  title: '网络请求失败',
                  icon: 'none'
                });
              }
            });
          } else {
            uni.hideLoading();
            uni.showToast({
              title: '微信登录失败',
              icon: 'none'
            });
          }
        },
        fail: (err) => {
          uni.hideLoading();
          uni.showToast({
            title: '微信登录失败',
            icon: 'none'
          });
        }
      });
    }
  }
}
</script>

<style>
.container {
  padding: 30rpx;
}

.header {
  text-align: center;
  margin-bottom: 50rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
}

.form-item {
  display: flex;
  align-items: center;
  margin-bottom: 30rpx;
}

.label {
  width: 180rpx;
  font-size: 28rpx;
}

.value, .input {
  flex: 1;
  font-size: 28rpx;
}

.input {
  border: 1px solid #ddd;
  border-radius: 8rpx;
  padding: 10rpx;
}

.pay-btn {
  margin-top: 50rpx;
  width: 90%;
}

.quick-btn {
  margin-top: 20rpx;
  width: 90%;
}

.tip {
  font-size: 24rpx;
  color: #999;
  text-align: center;
  margin-top: 20rpx;
}
</style>
